#ifndef _MAP_READER_H_
#define _MAP_READER_H_

#include <string>
#include <sstream>
#include <vector>
#include <fstream>
#include <functional>
#include <algorithm>
#include <utility>

namespace PathFinder
{
    typedef std::pair<int, int> Position;
    /// @note the map is column first
    struct Map
    {
        int rowLen;
        int rowNum;
        /// column first
        std::vector< std::vector<bool> > grid;
        Position initPos;
        Position dstPos;
    };

    /// convert char to bool
    struct char_to_bool
    :public std::unary_function<char, bool>
    {
        bool operator() (char src)
        {
            if( src == '0')
                return false;
            else
                return true;
        }
    };
    
    /// Ream map from file
    class MapReader
    {
    public:     
        /// Singleton method
        static MapReader& instance()
        {
            static MapReader instance_;
            return instance_;
        }
    
        void ReadMap(const std::string& fileName)
        {
            std::ifstream mapFile(fileName.c_str(), std::ios_base::in );

            map_.grid.clear();

            char dullChar;
            mapFile >> map_.rowLen;
            mapFile >> map_.rowNum;
            mapFile >> map_.initPos.first >> dullChar >> map_.initPos.second;
            mapFile >> map_.dstPos.first >> dullChar >> map_.dstPos.second;

            std::vector<bool> row;
            row.resize( map_.rowLen );
            for(int i = 0; i < map_.rowNum; i++)
            {
                std::string oneRow;
                mapFile >> oneRow;
                std::transform(oneRow.begin(), oneRow.end(), row.begin(), char_to_bool() );
                map_.grid.push_back( row );
            }
        }

        const Map& GetMap()
        {
            return map_;
        }
        
    private:
        Map map_;
    protected:
        MapReader() {}
        ~MapReader() {}
        MapReader(const MapReader&);
        MapReader& operator=(const MapReader&);
    };
}
#endif  // End definition of _MAP_READER_H_